package cn.ztf.zshop.sys.service.impl;

import cn.dev33.satoken.session.SaSessionCustomUtil;
import cn.dev33.satoken.stp.StpUtil;
import cn.ztf.zshop.common.exception.ZShopException;
import cn.ztf.zshop.common.utils.PageConverterVo;
import cn.ztf.zshop.sys.dao.SysMenuDao;
import cn.ztf.zshop.sys.dao.SysRoleDao;
import cn.ztf.zshop.sys.dao.SysUserDao;
import cn.ztf.zshop.sys.vo.MenuVo;
import cn.ztf.zshop.sys.vo.RoleVo;
import cn.ztf.zshop.sys.po.Menu;
import cn.ztf.zshop.sys.po.Role;
import cn.ztf.zshop.sys.service.SysRoleService;
import cn.ztf.zshop.sys.dto.RoleDto;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import ma.glasnost.orika.MapperFacade;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class SysRoleServiceImpl extends ServiceImpl<SysRoleDao, Role> implements SysRoleService {
    private final MapperFacade mapperFacade;
    private final SysMenuDao sysMenuDao;

    private final SysUserDao sysUserDao;

    @Override
    public Page<RoleVo> pageRole(Page<Role> page) {
        Page<Role> rolePage = lambdaQuery().page(page);
        Page<RoleVo> converterPage = PageConverterVo.converterPage(rolePage, RoleVo.class);
        return converterPage;
    }

    @Override
    public List<RoleVo> listRole() {
        List<Role> roles = baseMapper.selectList(null);
        List<RoleVo> list = roles.stream()
                .map(e -> mapperFacade.map(e, RoleVo.class))
                .collect(Collectors.toList());
        return list;
    }

    @Override
    public RoleVo getRoleById(Long roleId) {
        Role role = baseMapper.selectById(roleId);
        if (ObjectUtils.isEmpty(role)) {
            throw new ZShopException("该角色不存在");
        }
        List<Menu> menus = sysMenuDao.selectMenuByRole(roleId);
        List<MenuVo> menuVos = menus.stream()
                .map(e -> mapperFacade.map(e, MenuVo.class))
                .collect(Collectors.toList());
        RoleVo roleVo = mapperFacade.map(role, RoleVo.class);
        roleVo.setPermissions(menuVos);
        return roleVo;
    }

    @Transactional
    @Override
    public void create(RoleDto roleDto) {
        //TODO 设置当前创建人的id
        Role role = mapperFacade.map(roleDto, Role.class);
        long loginId = StpUtil.getLoginIdAsLong();
        role.setCreateUserId(loginId);
        // 创建角色信息
        baseMapper.insert(role);
        // 判断菜单权限是否为空
        if (!ObjectUtils.isEmpty(roleDto.getMenus())) {
            baseMapper.insertRoleMenu(role.getRoleId(), roleDto.getMenus());
        }
    }

    @Transactional
    @Override
    public void updateRole(RoleDto roleDto) {
        Role role = baseMapper.selectById(roleDto.getRoleId());
        if (ObjectUtils.isEmpty(role)) {
            throw new ZShopException("该角色不存在");
        }
        // 删除缓存中的  指定角色->权限
        SaSessionCustomUtil.deleteSessionById("role:"+roleDto.getRoleId());

        // 删除关系表
        baseMapper.deletedRoleMenuByRole(role.getRoleId());

        mapperFacade.map(roleDto, role);

        // 修改角色信息
        baseMapper.updateById(role);

        // 插入关系表
        if (!ObjectUtils.isEmpty(roleDto.getMenus())) {
            baseMapper.insertRoleMenu(role.getRoleId(), roleDto.getMenus());
        }

    }

    @Override
    public void delete(Long roleId) {
        // 查询是否有人正在占用该角色
        List<Long> userIds = sysUserDao.findUserIdByRoleId(roleId);
        if (ObjectUtils.isEmpty(userIds)) {
            baseMapper.deleteById(roleId);
            // 删除缓存中的  指定角色->权限
            SaSessionCustomUtil.deleteSessionById("role:"+roleId);
        }
        throw new ZShopException("当前角色正在被占用,无法删除");
    }
}
